Chicken()
This function acts like a class in plain JavaScript: calling 'new Chicken()' creates an object with its own x/y/velocity properties and methods (show, jump, duck, stand, update) attached via 'this'. It's a common pattern before ES6 class syntax became widespread, and it's still perfectly valid p5.js code.
🔬 The -15 value sets how hard the chicken launches upward. What happens to the jump arc if you change it to -25? What if you change it to -8?
this.jump = function() {
if (!this.isJumping) {
this.vy = -15; // Higher jump
this.isJumping = true;
this.isDucking = false; // Can't duck while jumping
}
};
function Chicken() {
this.x = 50;
this.y = groundY - 40; // Top-left of the bounding box
this.w = 30; // Effective width for standing bounding box
this.h = 40; // Effective height for standing bounding box
this.vy = 0; // Vertical velocity
this.gravity = 1;
this.isJumping = false;
this.isDucking = false;
this.show = function() {
fill(255, 200, 0); // Yellow for chicken body
noStroke();
if (this.isDucking) {
// Ducking chicken shape
// Body (squashed oval)
ellipse(this.x + this.w * 0.75, this.y + this.h * 0.75, this.w * 1.5, this.h * 0.5);
// Head (slightly lower)
ellipse(this.x + this.w * 1.2, this.y + this.h * 0.7, this.w / 2, this.h / 2);
// Beak
fill(255, 100, 0);
triangle(this.x + this.w * 1.2 + this.w / 4, this.y + this.h * 0.7,
this.x + this.w * 1.2 + this.w / 4, this.y + this.h * 0.7 + this.h / 8,
this.x + this.w * 1.2 + this.w / 2, this.y + this.h * 0.7 + this.h / 16);
// Legs (shorter)
stroke(150, 75, 0); // Brown for legs
strokeWeight(2);
line(this.x + this.w * 0.75 - 5, groundY, this.x + this.w * 0.75 - 5, groundY + 5);
line(this.x + this.w * 0.75 + 5, groundY, this.x + this.w * 0.75 + 5, groundY + 5);
} else {
// Standing chicken shape
// Body (oval)
ellipse(this.x + this.w / 2, this.y + this.h / 2, this.w, this.h);
// Head (smaller circle)
ellipse(this.x + this.w, this.y + this.h / 4, this.w / 2, this.h / 2);
// Beak (triangle)
fill(255, 100, 0); // Orange for beak
triangle(this.x + this.w + this.w / 4, this.y + this.h / 4,
this.x + this.w + this.w / 4, this.y + this.h / 4 + this.h / 8,
this.x + this.w + this.w / 2, this.y + this.h / 4 + this.h / 16);
// Comb (small triangles)
fill(200, 0, 0); // Red for comb
triangle(this.x + this.w, this.y, this.x + this.w + 5, this.y - 5, this.x + this.w + 10, this.y);
// Legs (lines)
stroke(150, 75, 0); // Brown for legs
strokeWeight(2);
line(this.x + this.w / 2 - 5, groundY, this.x + this.w / 2 - 5, groundY + 10);
line(this.x + this.w / 2 + 5, groundY, this.x + this.w / 2 + 5, groundY + 10);
}
};
this.jump = function() {
if (!this.isJumping) {
this.vy = -15; // Higher jump
this.isJumping = true;
this.isDucking = false; // Can't duck while jumping
}
};
this.duck = function() {
if (!this.isJumping) {
this.isDucking = true;
}
};
this.stand = function() {
this.isDucking = false;
};
this.update = function() {
// Apply gravity
this.y += this.vy;
this.vy += this.gravity;
// Prevent going below ground
this.y = constrain(this.y, 0, groundY - this.h);
// If on ground and not ducking, reset jumping state
if (this.y >= groundY - this.h && !this.isDucking) {
this.vy = 0;
this.isJumping = false;
}
// If on ground and ducking, reset jumping state
else if (this.y >= groundY - this.h && this.isDucking) {
this.vy = 0;
this.isJumping = false;
this.y = groundY - this.h / 2; // Chicken is half height when ducking
}
};
}
Line-by-line explanation (7 lines)
🔧 Subcomponents:
if (this.isDucking) { ... } else { ... }
Draws a squashed body shape when ducking, or the full upright body/head/comb/beak/legs when standing
if (!this.isJumping) { this.vy = -15; ... }
Only lets the chicken jump if it isn't already mid-air, preventing double/infinite jumps
this.y += this.vy; this.vy += this.gravity;
Moves the chicken by its current velocity, then accelerates that velocity downward by gravity - the classic Euler-integration jump arc
if (this.y >= groundY - this.h && !this.isDucking) { ... }
Detects when the chicken has touched the ground again and resets vy/isJumping so it can jump again
this.x = 50;- The chicken always stays at a fixed horizontal position - it never actually 'runs forward', the world scrolls past it instead
this.y = groundY - 40;- Positions the top of the chicken's bounding box so its feet sit on the ground line
this.gravity = 1;- How much downward acceleration is added to vy every frame - this is what pulls the chicken back down after a jump
if (this.isDucking) { ... } else { ... }- Chooses which set of ellipse/triangle/line calls to draw depending on whether the chicken is currently ducking
this.vy = -15; // Higher jump- Setting a negative vertical velocity launches the chicken upward instantly; gravity then slows and reverses it each frame
this.y = constrain(this.y, 0, groundY - this.h);- Clamps the chicken's y position so it can never fly above the top of the screen or sink below the ground
this.y = groundY - this.h / 2; // Chicken is half height when ducking- When landing while ducking, the chicken is repositioned lower since its effective height is halved